package org.egomsl.mw.segment;

import org.egomsl.mw.block.Block;
import org.egomsl.mw.record.Record;
import org.egomsl.mw.record.RecordScanner;

import java.util.Iterator;
import java.util.LinkedList;

public class ImmutableSegment {
    private boolean reversed;
    private LinkedList<Block> blocks;

    public ImmutableSegment(LinkedList<Block> blocks) {
        this.reversed = true;
        this.blocks = blocks;
    }

    public Iterator<Block> getBlocks() {
        if(blocks != null) {
            return blocks.iterator();
        }
        return null;
    }

    public boolean isReversed() {
        return reversed;
    }

    /**
     * 保证以指定的顺序返回块数据
     * @param reversed 是否逆序
     */
    public void ensureOrder(boolean reversed) {
        if(this.reversed != reversed) {
            LinkedList<Block> tmpBlocks = new LinkedList<>();
            while(blocks.size() > 0) {
                tmpBlocks.addLast(blocks.pollLast());
            }
            blocks = tmpBlocks;
            this.reversed = reversed;
        }
    }

    public RecordScanner getScaner() {
        return new SegmentRecordScanner(this);
    }

    class SegmentRecordScanner implements RecordScanner {
        private ImmutableSegment segment;

        RecordScanner blockRecordScanner;
        private Iterator<Block> blocks;

        public SegmentRecordScanner(ImmutableSegment segment) {
            this.blockRecordScanner = null;
            this.segment = segment;
            this.blocks = segment.getBlocks();
        }

        @Override
        public boolean hashNext() {
            if(blockRecordScanner == null && blocks.hasNext()) {
                blockRecordScanner = blocks.next().getScanner();
            }

            if(blockRecordScanner != null) {
                return blockRecordScanner.hashNext();
            }

            return false;
        }

        @Override
        public Record next() {
            return blockRecordScanner.next();
        }
    }

    public int getTotalSize() {
        int size = 0;
        for(Block block : blocks) {
            size += block.getLength();
        }
        return size;
    }
}
